import re
from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel, Field, validator, EmailStr, IPvAnyAddress

from common.utils import is_empty

from enum import Enum

class HostInfoScheme(str, Enum):
    http = 'http'
    https = 'https'


class StateInfo(str, Enum):
    enable = 'enable'
    disenable = 'disenable'

class ClassesInfo(str, Enum):
    class1 = 'K8s组件'
    class2 = 'K8s资源'
    class3 = 'prometheus'
    class4 = '中间件服务'
    class5 = 'ECS服务器'
    class6 = '站点监控'


class AlarmRuleType(str, Enum):
    alarm = 'alarm'
    record = 'record'

class DelBaseModel(BaseModel):
    uuid: int = Field(..., description="数据的uuid")



class PostHostInfo(BaseModel):
    name: str = Field(..., regex="^[-.a-z0-9]+$", description="主机名,正则:[.-a-z0-9]")
    scheme: HostInfoScheme = Field(HostInfoScheme.http, description="采集主机metrics信息url的协议,例如http/https")
    ip: IPvAnyAddress = Field(..., description="主机的ip地址")
    port: int = Field(..., description="采集主机metrics信息url的端口")
    metrics: str = Field(..., description="采集主机metrics信息url的上下文, 例如: /metrics")
    labels: dict = Field(..., description="主机的自定义标签")
    state: int = Field(1, description="主机的状态:1(使能) or 0(去使能)")
    comment: Optional[str] = Field("", description="主机说明")
    host_group_uuid: int = Field(..., description="主机所属主机组的uuid")


    @validator('scheme')
    def scheme_choices(cls, v):
        if v not in ["http", "https"]:
            raise ValueError('scheme is http or https')
        return v

    @validator('labels')
    def labels_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]*$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            if re.search(pattern, str(value)) is None:
                raise ValueError(f'value:[{value}] format error')
        return v


class PutHostInfo(BaseModel):
    scheme: HostInfoScheme = Field(HostInfoScheme.http, description="采集主机metrics信息url的协议,例如http/https")
    ip: IPvAnyAddress = Field(..., description="主机的ip地址")
    port: int = Field(..., description="采集主机metrics信息url的端口")
    metrics: str = Field(..., description="采集主机metrics信息url的上下文, 例如: /metrics")
    labels: dict = Field(..., description="主机的自定义标签")
    state: int = Field(1, description="主机的状态:1(使能) or 0(去使能)")
    comment: Optional[str] = Field("", description="主机说明")
    uuid: int = Field(..., description="物理机数据uuid")

    @validator('scheme')
    def scheme_choices(cls, v):
        if v not in ["http", "https"]:
            raise ValueError('scheme is http or https')
        return v

    @validator('labels')
    def labels_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]*$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            if re.search(pattern, str(value)) is None:
                raise ValueError(f'value:[{value}] format error')
        return v





class PostHostGroup(BaseModel):
    name: str = Field(..., description="主机组的名称")
    department_uuid: int = Field(..., description="主机组所属的部门")
    notice_teams_uuid: List[int] = Field(..., description="主机组关联的通知组uuid")
    comment: Optional[str] = Field("", description="主机组说明")


class PutHostGroup(BaseModel):
    uuid: int = Field(..., description="主机组数据uuid")
    comment: Optional[str] = Field("", description="主机组说明")

class PutHostGroupNotice(BaseModel):
    uuid: int = Field(..., description="主机组数据uuid")
    notice_teams_uuid: List[int] = Field(..., description="主机组关联的通知组uuid")

class PostDelHostGroupBindTemplate(BaseModel):
    host_group_uuid: int = Field(..., description="操作(绑定/解绑)的主机组uuid")
    template_uuid: int = Field(..., description="操作(绑定/解绑)的模板uuid")


class PostDelHostGroupAddHosts(BaseModel):
    host_group_uuid: int = Field(..., description="批量操作(添加/删除)的主机组uuid")
    hosts_uuid: List[int] = Field(..., description="批量操作(添加/删除)的主机uuid")


class PostDepartmentInfo(BaseModel):
    name: str = Field(..., description="部门名称")
    notice_teams_uuid: List[int] = Field(..., description="主机组关联的通知组uuid")
    comment: Optional[str] = Field("", description="部门说明")


class PutDepartmentInfo(BaseModel):
    uuid: int = Field(..., description="部门数据uuid")
    notice_teams_uuid: List[int] = Field(..., description="主机组关联的通知组uuid")
    comment: Optional[str] = Field("", description="部门说明")



class PostAlarmMetrics(BaseModel):
    name: str = Field(..., description="告警指标的名字")
    classes: ClassesInfo = Field(ClassesInfo.class1, description="告警指标的归类")
    type: AlarmRuleType = Field(..., description="告警指标的类型:record(记录规则) or alarm(告警规则)")
    expr: str = Field(..., description="告警指标的表达式")
    has_operator: int = Field(1, description="是否有操作符:1(有) or 0(没有)")
    parameters: List[str] = Field(..., description="需要的参数列表")
    annotations: dict = Field(..., description="告警指标的附加信息")
    comment: Optional[str] = Field("", description="告警指标的说明")

    @validator('annotations')
    def annotations_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]*$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            # value没有限制
        return v

class PutAlarmMetrics(BaseModel):
    expr: str = Field(..., description="告警指标的表达式")
    has_operator: int = Field(1, description="是否有操作符:1(有) or 0(没有)")
    parameters: List[str] = Field(..., description="需要的参数列表")
    annotations: dict = Field(..., description="告警指标的附加信息")
    comment: Optional[str] = Field("", description="告警指标的说明")
    uuid: int = Field(..., description="告警指标的数据uuid")

    @validator('annotations')
    def annotations_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]*$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            # value没有限制
        return v



class ExprOperator(str, Enum):
    operator1 = ''
    operator2 = '>='
    operator3 = '<'
    operator4 = '<='
    operator5 = '=='
    operator6 = '!='
    operator7 = '>'

class AlarmLevel(str, Enum):
    # 紧急告警 电话领导
    critical = 'critical'
    # 重要告警 电话
    major = 'major'
    # 一般告警 短信
    warning = 'warning'
    # 信息告警 企业微信
    info = 'info'
    # 无告警
    nothing = 'nothing'




class PostAlarmStrategy(BaseModel):
    name: str = Field(..., description="告警策略的名称")
    state: int = Field(1, description="告警策略的状态:1(使能) or 0(去使能)")
    alarm_metrics_uuid: int = Field(..., description="告警指标的uuid")
    alarm_metrics_parm: dict = Field(..., description="告警指标的参数")
    operator: ExprOperator = Field(..., description="告警策略操作符: >/>=/</<=/==/!=//")
    value: str = Field(..., description="告警策略的阈值")
    duration: int = Field(..., description="告警策略持续多长时间告警")
    notice_count: int = Field(1, description="告警通知的次数")
    level: AlarmLevel = Field(AlarmLevel.info, description="告警级别: critical(领导电话)/major(电话)/warning(短信)/info(企业微信)/nothing(无告警)")
    labels: dict = Field(..., description="告警策略自定义标签")
    annotations: dict = Field(..., description="告警策略自定义附加信息")
    maintain_begin: Optional[datetime] = Field(None, description="告警屏蔽开始时间")
    maintain_end: Optional[datetime] = Field(None, description="告警屏蔽结束时间")
    maintain_repeat: int = Field(0, description="告警屏蔽重复:1(屏蔽时间为每天这个时间段) or 0(默认,正常的时间段)")
    callback: Optional[str] = Field(..., description="回调函数")
    comment: Optional[str] = Field("", description="告警策略的说明")
    template_uuid: int = Field(..., description="告警策略所属的告警模板uuid")


    @validator('alarm_metrics_parm')
    def alarm_metrics_parm_choices(cls, v):
        result_v = v.copy()
        for key, value in v.items():
            pattern_key = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_=!~]*$')
            if re.search(pattern_key, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')

            if is_empty(value):
                result_v.pop(key)
            if isinstance(value, str):
                result_v[key] = value.replace(" ", "")
        return result_v


    @validator('labels')
    def labels_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]*$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            if re.search(pattern, str(value)) is None:
                raise ValueError(f'value:[{value}] format error')
        return v


    @validator('annotations')
    def annotations_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]*$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            # value没有限制
        return v

class PutAlarmStrategy(BaseModel):
    state: int = Field(1, description="告警策略的状态:1(使能) or 0(去使能)")
    alarm_metrics_uuid: int = Field(..., description="告警指标的uuid")
    alarm_metrics_parm: dict = Field(..., description="告警指标的参数")
    operator: ExprOperator = Field(..., description="告警策略操作符: >/>=/</<=/==/!=//")
    value: str = Field(..., description="告警策略的阈值")
    duration: int = Field(..., description="告警策略持续多长时间告警")
    notice_count: int = Field(1, description="告警通知的次数")
    level: AlarmLevel = Field(AlarmLevel.info, description="告警级别: critical(领导电话)/major(电话)/warning(短信)/info(企业微信)/nothing(无告警)")
    labels: dict = Field(..., description="告警策略自定义标签")
    annotations: dict = Field(..., description="告警策略自定义附加信息")
    maintain_begin: Optional[datetime] = Field(None, description="告警屏蔽开始时间")
    maintain_end: Optional[datetime] = Field(None, description="告警屏蔽结束时间")
    maintain_repeat: int = Field(0, description="告警屏蔽重复:1(屏蔽时间为每天这个时间段) or 0(默认,正常的时间段)")
    callback: Optional[str] = Field(..., description="回调函数")
    comment: Optional[str] = Field("", description="告警策略的说明")
    uuid: int = Field(..., description="告警策略的uuid")

    @validator('alarm_metrics_parm')
    def alarm_metrics_parm_choices(cls, v):
        result_v = v.copy()
        for key, value in v.items():
            pattern_key = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_=!~]*$')
            if re.search(pattern_key, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')

            if is_empty(value):
                result_v.pop(key)
            if isinstance(value, str):
                result_v[key] = value.replace(" ", "")
        return result_v

    @validator('labels')
    def labels_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]+$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            if re.search(pattern, str(value)) is None:
                raise ValueError(f'value:[{value}] format error')
        return v

    @validator('annotations')
    def annotations_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]+$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            # value没有限制
        return v

class PostHostStrategy(BaseModel):
    name: str = Field(..., description="主机告警策略的名称")
    state: int = Field(1, description="主机告警策略的状态:1(使能) or 0(去使能)")
    alarm_metrics_uuid: int = Field(..., description="告警指标的uuid")
    alarm_metrics_parm: dict = Field(..., description="告警指标的参数")
    operator: ExprOperator = Field(..., description="告警策略操作符: >/>=/</<=/==/!=//")
    value: str = Field(..., description="告警策略的阈值")
    duration: int = Field(..., description="告警策略持续多长时间告警")
    notice_count: int = Field(1, description="告警通知的次数")
    level: AlarmLevel = Field(AlarmLevel.info, description="告警级别: critical(领导电话)/major(电话)/warning(短信)/info(企业微信)/nothing(无告警)")
    labels: dict = Field(..., description="告警策略自定义标签")
    annotations: dict = Field(..., description="告警策略自定义附加信息")
    maintain_begin: Optional[datetime] = Field(None, description="告警屏蔽开始时间")
    maintain_end: Optional[datetime] = Field(None, description="告警屏蔽结束时间")
    maintain_repeat: int = Field(0, description="告警屏蔽重复:1(屏蔽时间为每天这个时间段) or 0(默认,正常的时间段)")
    callback: Optional[str] = Field(..., description="回调函数")
    comment: Optional[str] = Field("", description="告警策略的说明")
    host_uuid: int = Field(..., description="物理机uuid")
    priority: int = Field(..., description="告警策略的优先级:1(优先) or 0(共存)")

    @validator('alarm_metrics_parm')
    def alarm_metrics_parm_choices(cls, v):
        result_v = v.copy()
        for key, value in v.items():
            pattern_key = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_=!~]*$')
            if re.search(pattern_key, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')

            if is_empty(value):
                result_v.pop(key)
            if isinstance(value, str):
                result_v[key] = value.replace(" ", "")
        return result_v

    @validator('labels')
    def labels_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]+$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            if re.search(pattern, str(value)) is None:
                raise ValueError(f'value:[{value}] format error')
        return v

    @validator('annotations')
    def annotations_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]+$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            # value没有限制
        return v

class PutHostStrategy(PostHostStrategy):
    state: int = Field(1, description="主机告警策略的状态:1(使能) or 0(去使能)")
    alarm_metrics_uuid: int = Field(..., description="告警指标的uuid")
    alarm_metrics_parm: dict = Field(..., description="告警指标的参数")
    operator: ExprOperator = Field(..., description="告警策略操作符: >/>=/</<=/==/!=//")
    value: str = Field(..., description="告警策略的阈值")
    duration: int = Field(..., description="告警策略持续多长时间告警")
    notice_count: int = Field(1, description="告警通知的次数")
    level: AlarmLevel = Field(AlarmLevel.info, description="告警级别: critical(领导电话)/major(电话)/warning(短信)/info(企业微信)/nothing(无告警)")
    labels: dict = Field(..., description="告警策略自定义标签")
    annotations: dict = Field(..., description="告警策略自定义附加信息")
    maintain_begin: Optional[datetime] = Field(None, description="告警屏蔽开始时间")
    maintain_end: Optional[datetime] = Field(None, description="告警屏蔽结束时间")
    maintain_repeat: int = Field(0, description="告警屏蔽重复:1(屏蔽时间为每天这个时间段) or 0(默认,正常的时间段)")
    callback: Optional[str] = Field(..., description="回调函数")
    comment: Optional[str] = Field("", description="告警策略的说明")
    host_uuid: int = Field(..., description="物理机uuid")
    priority: int = Field(..., description="告警策略的优先级:1(优先) or 0(共存)")
    uuid: int = Field(..., description="告警策略的uuid")

    @validator('alarm_metrics_parm')
    def alarm_metrics_parm_choices(cls, v):
        result_v = v.copy()
        for key, value in v.items():
            pattern_key = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_=!~]*$')
            if re.search(pattern_key, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')

            if is_empty(value):
                result_v.pop(key)
            if isinstance(value, str):
                result_v[key] = value.replace(" ", "")
        return result_v

    @validator('labels')
    def labels_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]+$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            if re.search(pattern, str(value)) is None:
                raise ValueError(f'value:[{value}] format error')
        return v

    @validator('annotations')
    def annotations_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]+$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            # value没有限制
        return v


class PostAlarmTemplate(BaseModel):
    name: str = Field(..., description="告警模板的名字")
    classes: ClassesInfo = Field(..., description="告警模板的归类")
    comment: Optional[str] = Field("", description="告警模板的说明")


class PutAlarmTemplate(BaseModel):
    comment: Optional[str] = Field("", description="告警模板的说明")
    uuid: int = Field(..., description="告警模板的uuid")



class PostAlarmRule(BaseModel):
    name: str = Field(..., regex="^[-.a-zA-Z0-9:]+$", description="告警规则的名称,正则:[.-a-zA-Z0-9:]")
    type: AlarmRuleType = Field(AlarmRuleType.alarm, description="告警规则的类型:record(记录规则) or alarm(告警规则)")
    state: bool = Field(1, description="告警规则的状态:1(使能) or 0(去使能)")
    target: str = Field(..., description="监控目标")
    alarm_metrics_uuid: int = Field(..., description="告警指标的uuid")
    alarm_metrics_parm: dict = Field(..., description="告警指标的参数")
    operator: ExprOperator = Field(..., description="告警策略操作符: >/>=/</<=/==/!=//")
    value: str = Field(..., description="告警策略的阈值")
    duration: int = Field(..., description="告警规则持续多长时间告警")
    notice_teams_uuid: List[int] = Field(..., description="告警通知组的uuid")
    notice_count: int = Field(1, description="告警通知的次数")
    level: AlarmLevel = Field(AlarmLevel.info, description="告警级别: critical(领导电话)/major(电话)/warning(短信)/info(企业微信)/nothing(无告警)")
    maintain_begin: Optional[datetime] = Field(None, description="告警屏蔽开始时间")
    maintain_end: Optional[datetime] = Field(None, description="告警屏蔽时间")
    maintain_repeat: int = Field(0, description="告警屏蔽重复:1(屏蔽时间为每天这个时间段) or 0(默认,正常的时间段)")
    callback: Optional[str] = Field("", description="告警回调url")
    labels: Optional[dict] = Field({}, description="告警规则自定义标签")
    annotations: Optional[dict] = Field({}, description="告警规则自定义附件信息")
    comment: Optional[str] = Field("", description="告警规则的说明")
    alarm_group_uuid: int = Field(..., description="告警规则所属的告警组uuid")


    @validator('alarm_metrics_parm')
    def alarm_metrics_parm_choices(cls, v):
        result_v = v.copy()
        for key, value in v.items():
            pattern_key = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_=!~]*$')
            if re.search(pattern_key, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')

            if is_empty(value):
                result_v.pop(key)
            if isinstance(value, str):
                result_v[key] = value.replace(" ", "")
        return result_v

    @validator('labels')
    def labels_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]+$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            if re.search(pattern, str(value)) is None:
                raise ValueError(f'value:[{value}] format error')
        return v

    @validator('annotations')
    def annotations_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]+$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            # value没有限制
        return v


class PutAlarmRule(BaseModel):
    uuid: int = Field(..., description="告警规则的uuid")
    state: bool = Field(1, description="告警规则的状态:1(使能) or 0(去使能)")
    target: str = Field(..., description="监控目标")
    alarm_metrics_uuid: int = Field(..., description="告警指标的uuid")
    alarm_metrics_parm: dict = Field({}, description="告警指标的参数")
    operator: ExprOperator = Field(..., description="告警策略操作符: >/>=/</<=/==/!=//")
    value: str = Field("", description="告警策略的阈值")
    duration: int = Field("", description="告警规则持续多长时间告警")
    notice_teams_uuid: List[int] = Field([], description="告警通知组的uuid")
    notice_count: int = Field(1, description="告警通知的次数")
    level: AlarmLevel = Field(AlarmLevel.info, description="告警级别: critical(领导电话)/major(电话)/warning(短信)/info(企业微信)/nothing(无告警)")
    maintain_begin: Optional[datetime] = Field(None, description="告警屏蔽开始时间")
    maintain_end: Optional[datetime] = Field(None, description="告警屏蔽时间")
    maintain_repeat: int = Field(0, description="告警屏蔽重复:1(屏蔽时间为每天这个时间段) or 0(默认,正常的时间段)")
    callback: Optional[str] = Field("", description="告警回调url")
    labels: Optional[dict] = Field({}, description="告警规则自定义标签")
    annotations: Optional[dict] = Field({}, description="告警规则自定义附件信息")
    comment: Optional[str] = Field("", description="告警规则的说明")

    @validator('alarm_metrics_parm')
    def alarm_metrics_parm_choices(cls, v):
        result_v = v.copy()
        for key, value in v.items():
            pattern_key = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_=!~]*$')
            if re.search(pattern_key, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')

            if is_empty(value):
                result_v.pop(key)
            if isinstance(value, str):
                result_v[key] = value.replace(" ", "")
        return result_v

    @validator('labels')
    def labels_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]+$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            if re.search(pattern, str(value)) is None:
                raise ValueError(f'value:[{value}] format error')
        return v

    @validator('annotations')
    def annotations_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]+$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            # value没有限制
        return v



class PostAlarmGroup(BaseModel):
    name: str = Field(..., regex="^[-.a-z0-9]+$", description="告警规则组的名称,正则:[-.a-z0-9]")
    alarm_set_uuid: int = Field(..., description="告警规则组所属的告警规则集的uuid")
    comment: Optional[str] = Field("", description="告警规则组的说明")

class PutAlarmGroup(BaseModel):
    uuid: int = Field(..., description="告警规则组的uuid")
    comment: Optional[str] = Field("", description="告警规则组的说明")


class PostAlarmSet(BaseModel):
    name: str = Field(..., regex="^[-.a-z0-9]+$", description="告警规则集的名称,正则:[.-a-z0-9]")
    classes: ClassesInfo = Field(ClassesInfo.class1,description="告警规则集的归类,例如: k8s容器/ECS服务器")
    comment: Optional[str] = Field("", description="告警规则集的说明")

class PutAlarmSet(BaseModel):
    uuid: int = Field(..., description="告警规则集的uuid")
    comment: Optional[str] = Field("", description="告警规则集的说明")

class PutAlarmSetSync(BaseModel):
    uuid: int = Field(..., description="告警规则集的uuid")

class PutAlarmRecord(BaseModel):
    uuid: int = Field(..., description="告警记录的uuid")
    state: int = Field(1, description="告警记录的状态:1(正常告警) or 0(关闭告警)")
    comment: Optional[str] = Field("", description="告警记录的说明")

class RecordStatus(str, Enum):
    firing = 'firing'
    resolved = 'resolved'


class PostAlarmRecord(PutAlarmRecord):
    name: str = Field(..., description="告警记录的名字")
    classes: ClassesInfo = Field(ClassesInfo.class1, description="告警记录归类,例如: k8s容器/ECS服务器")
    status: RecordStatus = Field(RecordStatus.firing, description="告警记录的状态,例如: firing/resolved")
    number: int = Field(..., description="告警记录的次数")
    fingerprint: str = Field(..., description="告警记录的指纹")
    labels: dict = Field(..., description="告警记录的标签")
    annotations: dict = Field(..., description="告警记录的附加信息")
    starts_at: Optional[datetime] = Field(None, description="告警开始时间")
    ends_at: Optional[datetime] = Field(None, description="告警结束时间")
    comment: Optional[str] = Field("", description="告警记录的说明")


    @validator('labels')
    def labels_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_=!~]+$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            if re.search(pattern, str(value)) is None:
                raise ValueError(f'value:[{value}] format error')
        return v

    @validator('annotations')
    def annotations_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]+$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            # value没有限制
        return v

class NetworkProbeModule(str, Enum):
    http = 'http'
    tcp = 'tcp'
    icmp = "icmp"

class PostNetworkProbe(BaseModel):
    name: str = Field(..., regex="^[-.a-z0-9]+$", description="探测名称,正则:[.-a-z0-9]")
    module: NetworkProbeModule = Field(..., description="探测任务模型,例如http/tcp/icmp")
    targets: List[str] = Field(..., description="探测目标")
    labels: dict = Field(..., description="探测任务标签")
    state: int = Field(1, description="探测任务的状态:1(使能) or 0(去使能)")
    comment: Optional[str] = Field("", description="探测任务说明")
    network_group_uuid: int = Field(..., description="探测任务所属组的uuid")


    @validator('labels')
    def labels_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]*$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            if re.search(pattern, str(value)) is None:
                raise ValueError(f'value:[{value}] format error')
        return v



class PutNetworkProbe(BaseModel):
    targets: List[str] = Field(..., description="探测目标")
    labels: dict = Field(..., description="探测任务标签")
    state: int = Field(1, description="探测任务的状态:1(使能) or 0(去使能)")
    comment: Optional[str] = Field("", description="探测任务说明")
    uuid: int = Field(..., description="物理机数据uuid")

    @validator('labels')
    def labels_choices(cls, v):
        for key, value in v.items():
            pattern = re.compile(r'^[a-zA-Z][-.a-zA-Z0-9_]*$')
            if re.search(pattern, str(key)) is None:
                raise ValueError(f'key:[{key}] format error')
            if re.search(pattern, str(value)) is None:
                raise ValueError(f'value:[{value}] format error')
        return v



class PostNetworkGroup(BaseModel):
    name: str = Field(..., description="网络探测组的名称")
    department_uuid: int = Field(..., description="网络探测组所属的部门")
    notice_teams_uuid: List[int] = Field(..., description="网络探测组关联的通知组uuid")
    comment: Optional[str] = Field("", description="网络探测组说明")


class PutNetworkGroup(BaseModel):
    uuid: int = Field(..., description="网络探测组数据uuid")
    comment: Optional[str] = Field("", description="网络探测组说明")

class PutNetworkGroupNotice(BaseModel):
    uuid: int = Field(..., description="网络探测组数据uuid")
    notice_teams_uuid: List[int] = Field(..., description="网络探测组关联的通知组uuid")

class PostDelHostNetworkBindTemplate(BaseModel):
    network_group_uuid: int = Field(..., description="操作(绑定/解绑)的网络探测组uuid")
    template_uuid: int = Field(..., description="操作(绑定/解绑)的模板uuid")


class PostNetworkGroupAddProbes(BaseModel):
    network_group_uuid: int = Field(..., description="批量操作(添加/删除)的网络探测组uuid")
    network_probes_uuid: List[int] = Field(..., description="批量操作(添加/删除)的网络探测任务uuid")
